package com.quan.system.web.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.quan.common.annotation.Log;
import com.quan.common.bean.MailBean;
import com.quan.common.bean.PageBean;
import com.quan.common.bean.R;
import com.quan.common.core.MyBaseController;
import com.quan.common.enums.LogType;
import com.quan.common.utils.DateUtils;
import com.quan.common.utils.PasswordUtils;
import com.quan.common.utils.RandomUitl;
import com.quan.system.common.amqp.producer.ProducerMessageSendMail;
import com.quan.system.common.vo.SystemUserVo;
import com.quan.system.entity.SystemUser;
import com.quan.system.entity.SystemUserRole;
import com.quan.system.service.SystemUserRoleService;
import com.quan.system.service.SystemUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * <p>
 * 通用用户权限系统-用户表 前端控制器
 * </p>
 *
 * @author 杨浩泉
 * @since 2019-06-03
 */
@Api(tags ="系统用户管理")
@RestController
@RequestMapping("/system/user")
public class SystemUserController extends MyBaseController {
	
	@Autowired
	private SystemUserService service;

	@Autowired
	private SystemUserRoleService systemUserRoleService;
	
	@Autowired
	private ProducerMessageSendMail producerMessageSendMail;

	/**
	 * 添加
	 * 
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@ApiOperation(value = "添加用户")
	@PostMapping("/add") @Log(type=LogType.BUSINESS, desc = "添加")
	public Object add(@Valid @RequestBody SystemUser entity, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return R.warning(bindingResult.getFieldError().getRejectedValue().toString());
		}
		
		if(this.service.hasExist("username", entity.getUsername(), SystemUser.class)) {
			return R.warning("该值已存在");
		}

		boolean save = this.service.save(entity);
		if (save) {
			return R.ok("提交成功");
		} else {
			return R.failure("提交失败");
		}
	}

	/**
	 * 根据ID删除
	 * 
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "根据ID删除")
	@GetMapping("/deleteById/{id}") @Log(type=LogType.BUSINESS, desc = "根据ID删除")
	public Object deleteById(@PathVariable String id) {
		if (StringUtils.isNotBlank(id)) {
			boolean remove = this.service.removeById(id);
			if (remove) {
				return R.ok();
			} else {
				return R.failure("通过ID删除失败：[ " + id + " ]");
			}
		}
		return R.failure("请选项需要删除的记录");
	}

	/**
	 * 批量删除
	 * 
	 * @param params idList:["1","2"]
	 * @return
	 */
	@ApiOperation(value = "批量删除")
	@PostMapping("/deleteBatchIds") @Log(type=LogType.BUSINESS, desc = "根据ID批量删除")
	public Object deleteBatchIds(@RequestBody Map<String, Object> params) {
		if (null != params && !params.isEmpty()) {
			List<Long> idList = JSON.parseArray(params.get("idList").toString(), Long.class);
			boolean remove = this.service.removeByIds(idList);
			if (remove) {
				return R.ok();
			} else {
				return R.failure("通过ID删除失败：[ " + idList + " ]");
			}
		}
		return R.failure("请选项需要删除的记录");
	}

	/**
	 * 修改
	 * 
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@ApiOperation(value = "修改")
	@PostMapping("/update") @Log(type=LogType.BUSINESS, desc = "修改")
	public Object update(@Valid @RequestBody SystemUser entity, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return R.failure(bindingResult.getFieldError().getDefaultMessage().toString());
		}
		boolean update = this.service.updateById(entity);
		if (update) {
			return R.ok("修改成功");
		} else {
			return R.failure("修改失败");
		}
	}

	/**
	 * 根据ID查询
	 * 
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "根据ID查询")
	@GetMapping("/get/{id}") @Log(type=LogType.BUSINESS, desc = "根据ID查询")
	public Object get(@PathVariable Long id) {
		SystemUser entity = this.service.getById(id);
		if (null != entity) {
			return R.ok(entity);
		} else {
			return R.failure("通过ID查询失败：[ " + id + " ]");
		}
	}

	/**
	 * 查询所有数据，不分页
	 * 
	 * @param entity
	 * @return
	 */
	@ApiOperation(value = "查询所有数据，不分页")
	@GetMapping(value = "/list") @Log(type=LogType.BUSINESS, desc = "查询所有数据")
	public Object list(SystemUser entity) {
		return R.ok(this.service.list(new QueryWrapper<SystemUser>(entity)));
	}

	/**
	 * 分页查询数据
	 * 
	 * @param entity
	 * @return
	 */
	@ApiOperation(value = "分页查询数据")
	@GetMapping(value = "/page") @Log(type=LogType.BUSINESS, desc = "分页查询数据")
	public Object page(SystemUser entity) {
		return R.ok(this.service.selectPage(new QueryWrapper<SystemUser>(entity).orderByDesc("ctime"), new PageBean(request)));
	}
	
	/**
	 * 根据用户ID加载用户对应的角色
	 * @param userId
	 * @return
	 */
	@ApiOperation(value = "根据用户ID加载用户对应的角色")
	@GetMapping(value = "/getRolesByUserId/{userId}") @Log(type=LogType.BUSINESS, desc = "根据用户ID加载用户对应的角色")
	public Object getRolesByUserId(@PathVariable String userId) {
		QueryWrapper<SystemUserRole> queryWrapper = new QueryWrapper<SystemUserRole>();
		queryWrapper.eq("user_id", userId);
		return R.ok(this.systemUserRoleService.list(queryWrapper));
	}
	
	
	/**
	 * 添加、修改、删除用户与角色关联
	 * @param map {"userId": 1, "roles": [1, 2]}
	 * @return
	 */
	@ApiOperation(value = "添加、修改、删除用户与角色关联")
    @PostMapping("/setUserRole") @Log(type=LogType.BUSINESS, desc = "添加、修改、删除用户与角色关联")
    public Object setUserRole(@RequestBody Map<String, Object> map) {
    	
    	String userId = map.get("userId").toString() ;
    	JSONArray parseArray = JSON.parseArray(map.get("roles").toString()) ;
    	
    	if(null != userId) {
    		QueryWrapper<SystemUserRole> queryWrapperDeleteByUserId = new QueryWrapper<SystemUserRole>();
    		queryWrapperDeleteByUserId.eq("user_id", userId);
    		this.systemUserRoleService.remove(queryWrapperDeleteByUserId);
    		
        	if(!parseArray.isEmpty()) {
        		for(int i=0; i<parseArray.size(); i++) {
        			
					  SystemUserRole entity = new SystemUserRole() ;
					  entity.setUserId(Long.parseLong(userId));
					  entity.setRoleId(parseArray.getInteger(i));
					  
					  this.systemUserRoleService.save(entity);
        		}
        	}
    	}
    	
		return R.ok();
    }
    
    /**
	 * 重置用户登陆密码为[123456]
	 * 
	 * @param params idList:["1","2"]
	 * @return
	 */
	@ApiOperation(value = "重置用户登陆密码为[123456]")
	@PostMapping("/batchResetPassword") @Log(type=LogType.BUSINESS, desc = "重置用户登陆密码为[123456]")
	public Object batchResetPassword(@RequestBody Map<String, Object> params) {
		if (null != params && !params.isEmpty()) {
			List<Long> idList = JSON.parseArray(params.get("idList").toString(), Long.class);
			boolean flag = this.service.batchResetPassword(idList);
			if (flag) {
				return R.ok();
			} else {
				return R.failure("重置用户登陆密码失败：[ " + idList + " ]");
			}
		}
		return R.failure("请选项需要重置用户登陆密码的记录");
	}
    
    
    /**
	 * 修改个人登录密码
	 * 
	 * @param dto
	 * @return
	 */
	@ApiOperation(value = "修改个人登录密码")
	@PostMapping(value = "/updateMyPassword") @Log(type=LogType.BUSINESS, desc = "修改个人登录密码")
	public Object updateMyPassword(@RequestBody SystemUserVo dto) {
		try {
			if (StringUtils.isBlank(dto.getOldPassword())) {
				return R.warning("原密码不能为空");	
			}
			if (StringUtils.isBlank(dto.getNewPassword())) {
				return R.warning("新密码不能为空");
			}
			this.service.updatePassword(dto.getId(), dto.getOldPassword(), dto.getNewPassword());
			return R.ok();
		} catch (RuntimeException e) {
			return R.failure(e.getMessage());
		}
	}

	/**
	 * 修改个人基本信息
	 * 
	 * @param entity
	 * @return
	 */
	@ApiOperation(value = "修改个人基本信息")
	@PostMapping(value = "/updateMyInfo") @Log(type=LogType.BUSINESS, desc = "修改个人基本信息")
	public Object updateMyInfo(@RequestBody SystemUser entity) {
		if (StringUtils.isBlank(entity.getRealname())) {
			return R.warning("姓名不能为空");
		}
		if (StringUtils.isBlank(entity.getEmail())) {
			return R.warning("邮件地址不能为空");
		}
		if (StringUtils.isBlank(entity.getMobile())) {
			return R.warning("手机号码不能为空");
		}

		entity.setPassword(null);
		entity.setSalt(null);
		this.service.updateById(entity) ;

		return R.ok();
	}
	
	/**
	 * 忘记密码，进行邮件通知
	 * @param entity
	 * @return
	 */
	@ApiOperation(value = "忘记密码，进行邮件通知")
	@PostMapping(value = "/forgetPasswordSendMail")
	public Object forgotPasswordSendMail(@RequestBody SystemUser entity) {
		if (StringUtils.isBlank(entity.getEmail())) {
			return R.warning("邮件地址不能为空");
		}
		
		QueryWrapper<SystemUser> queryWrapper = new QueryWrapper<SystemUser>() ;
		queryWrapper.eq("email", entity.getEmail());
		SystemUser user = this.service.getOne(queryWrapper, false);
		if(null == user) {
			return R.warning("邮箱地址不存在！");
		}
		
		// 修改密码凭证
		String resetPwdToken = RandomUitl.uuid() ;
		
		user.setToken(resetPwdToken);
		// 修改密码的凭证有效时间为30分钟内
		user.setExpire(DateUtils.computeMinute(+30));
		this.service.updateById(user);
		
		// 发送短信或邮件告知用户账号和密码
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("subject", "密码找回");
		map.put("resetPwdToken", resetPwdToken);
		
		MailBean mailBean = new MailBean();
		mailBean.setTo(entity.getEmail());
		mailBean.setSubject(map.get("subject").toString());
		mailBean.setTemplateLocation("mail/ForgetPassword.html");
		mailBean.setTemplateData(map);
		
		this.producerMessageSendMail.sender(mailBean);

		return R.ok("邮件已发送");
	}
	
	/**
	 * 用户找回密码，重新修改密码
	 * @param entity
	 * @return
	 */
	@ApiOperation(value = "用户找回密码，重新修改密码")
	@PostMapping(value = "/forgetPasswordByUpdate")
	public Object forgetPasswordByUpdate(@RequestBody SystemUser entity) {
		if (StringUtils.isBlank(entity.getPassword())) {
			return R.warning("密码不能为空");
		}
		
		QueryWrapper<SystemUser> queryWrapper = new QueryWrapper<SystemUser>() ;
		queryWrapper.eq("token", entity.getToken());
		SystemUser user = this.service.getOne(queryWrapper, false);
		
		if(null == user) {
			return R.warning("修改密码的凭证不存在！");
		}
		
		if(new Date().getTime() > user.getExpire()) {
			return R.warning("修改密码凭证失效，请重新申请找回密码！");
		}
		
		// 加密盐
		user.setSalt(RandomUitl.uuid());
		String password = entity.getPassword(); // 生成6位随机密码
		user.setPassword(PasswordUtils.encodePassword(password, user.getSalt()));
		user.setExpire(0L);
		user.setToken("");
		this.service.updateById(user);
		

		return R.ok("密码修改成功，请重新登陆");
	}

}
